package it.polimi.swimv2.session;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import it.polimi.swimv2.entities.Ability;
import it.polimi.swimv2.entities.Feedback;
import it.polimi.swimv2.entities.HelpRequest;
import it.polimi.swimv2.entities.User;
import it.polimi.swimv2.exception.FeedbackException;
import it.polimi.swimv2.remote.FeedbackManagerRemote;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 * Session Bean implementation class FeedbackManager
 */
@Stateless
public class FeedbackManager implements FeedbackManagerRemote, FeedbackManagerLocal {
	
	@PersistenceContext(unitName = "swimv2")
	private EntityManager em;
    
	/**
     * Default constructor. 
     */
    public FeedbackManager() {
        
    }

	@Override
	public void sendFeedback(String comment, int score, Integer helpRequestId)
			throws FeedbackException {
		
		HelpRequest hr=em.find(HelpRequest.class,helpRequestId);
		if(!hr.isFeedbackAvailable()||scoreOutOfRange(score))
			throw new FeedbackException();
		Feedback newFeedback=new Feedback(hr,score,comment);
		hr.setFeedbackAvailable(false);
		em.persist(newFeedback);
		updateUserTotScore(hr.getReceiver());
		em.flush();
		return;
	}

	private boolean scoreOutOfRange(int score) {
		return score>10||score<=0;
	}
	
	public void deleteFeedback(Ability a) {
		Query q=em.createQuery("SELECT OBJECT(f) FROM Feedback f WHERE f.ability= :ab");
		q.setParameter("ab", a);
		@SuppressWarnings("unchecked")
		List<Feedback> result=q.getResultList();
		Set<User> toBeUpdated=new HashSet<User>();
		for(Feedback f:result){
			toBeUpdated.add(f.getReceiver());
			em.remove(f);
		}
		for(User u: toBeUpdated){
			updateUserTotScore(u);
		}
	}
	
	private void updateUserTotScore(User receiver) {
		Query q = em.createQuery("SELECT OBJECT(fb) "+
									"FROM Feedback fb " +
									"WHERE receiver=:user");
		q.setParameter("user", receiver);
		@SuppressWarnings("unchecked")
		List<Feedback> feedbacksreceived= q.getResultList();
		receiver.setTotScore(calculateTotScore(feedbacksreceived));
	}

	private float calculateTotScore(List<Feedback> feedbacksreceived) {
		
		if(feedbacksreceived.isEmpty()){
			return 0;
		}
		int sum=0; int count=0;
		for(Feedback f:feedbacksreceived){
			sum+=f.getScore();
			count++;
		}
		return sum/count;
		
	}

}
